package com.firemoss.magicbus.messaging
{
	import com.firemoss.magicbus.messaging.fillter.ResponseFilterChain;
	
	import flash.events.Event;
	
	import mx.messaging.Consumer;
	import mx.messaging.events.MessageEvent;

	/**
	 *  You shouldn't have to be an expert in Flex messaging to use it.  
	 *  <p>
	 * 	The ConsumerMediator simplifies using a consumer so that all you have to do
	 *  is configure it once then write your business logic - you don't deal with Flex messaging at all.  
	 *  <p>
	 *  In its simplest use,
	 *  you just state what event name should be dispatched upon receipt of a message,
	 *  and it'll construct an event of that name that can be handled by any Swiz
	 *  event listener, such as a [Mediate]'d method.
	 *  </p><p>
	 *  For example, if you wanted to have ChatController's messageReceived( message : String )
	 *  method get messages coming from a consumer, you'd do the following in Beans.mxml:
	 *  </p><p>
	 *  &lt;messaging:ConsumerMediator consumer="{ chatConsumer }" messageEvent="chatMessageReceived" bodyProperty="message" /&gt;
	 *  </p><p>
	 * 
	 *  Then, in a controller:
	 *  </p><p>
	 *  [Mediate( event="chatMessageReceived", properties="message" )]
	 *  public function messageReceived( message : String ) : void
	 *  {
	 *    // your logic
	 *  }
	 *  </p>
	 */	
 	public class AbstractConsumerMediator extends AbstractMessageAgentMediator implements IConsumerMediator
	{
		// PUBLIC PROPERTIES
		
		public var clientId : String
		
		public var messageConverter : IConsumerMessageConverter

		public var responseChain : ResponseFilterChain
		
		public function set responseFilters( value : Object ) : void
		{
			if ( !value ) return
			
			if ( !( value is Array ) ) { value = [ value ] }
			
			responseChain = new ResponseFilterChain( value as Array )
		}

		public function set connectionRequestedEvents( eventNames : Array ) : void
		{
			subscribeToConnectionRequests( eventNames )
		}
		
		public function set messageEvent( value : String ): void
		{
			_messageEvent = value
		}
		public function get messageEvent() : String
		{
			return _messageEvent
		}
		private var _messageEvent : String;
		
		private var _consumer : Consumer
		public function set consumer( consumer : Consumer ) : void
		{
			super.messageAgent = consumer
			
			if ( _consumer )
			{
				_consumer.removeEventListener( MessageEvent.MESSAGE, messageHandler )
			}
			
			_consumer = consumer
			
			if ( _consumer )
			{
				_consumer.addEventListener( MessageEvent.MESSAGE, messageHandler, false, 0, true )
			}
		}
		public function get consumer() : Consumer
		{
			return _consumer
		}
		
		public function AbstractConsumerMediator()
		{
			messageConverter = new DefaultConsumerMessageConverter( this )
			
			converter = messageConverter
		}
		
		// IConsumerMediator stubs
		
		public function subscribeToConnectionRequests( eventNames : Array ) : void
		{
			// NO-OP:  implement in subclasses!
		}
		
		// NOTIFICATION LISTENERS
		
		protected function connectionRequested( event : Event ) : void
		{
			if ( consumer )
			{
				consumer.subscribe( clientId ? clientId : null )
			}
		}
		
		// CONSUMER EVENT LISTENERS
		
		private function messageHandler( event : MessageEvent ) : void
		{
			if ( messageConverter)
			{
				var notification : Event = messageConverter.convert( this, event )
				
				if ( notification )
				{
					if ( responseChain )
					{
						responseChain.execute( [ notification ] )
					}

					dispatch( notification )
				}
			}
		}
				
	}
}